﻿using System;
using System.ComponentModel;
using System.Drawing;
using ArtMath.Component.Point;
using ArtMath.PointCollection;
using ArtMath.Component.Line;
using ArtMath.Core.Data;
using ArtMath.Core.Helper;
using ArtMath.Data;
using ArtMath.Setting;
using ArtMath.Resource;
using ArtMath.Attribute;
using ArtMath.CommonType;

namespace ArtMath.Component.CoordinateSystem
{
    /// <summary>
    /// 极坐标系
    /// </summary>
    [Serializable]
    public class PolarCoordinate : CoordinateBase
    {
        bool showOx = true;
        PolarAxis jz;
        public PolarCoordinate(SketchPad pad) : base(pad, Resources.Translate("PolarCoordinate"), ToolTypeName.jzbx)
        {
        }
        public override PointCollectionsManager Skeleton
        {
            get
            {
                return PolarAxis.Skeleton;
            }
        }
        public override PointCollectionsManager PSkeleton
        {
            get
            {
                return PolarAxis.PSkeleton;
            }
        }
        public override PointCollectionsManager NewSkeleton
        {
            get
            {
                return PolarAxis.NewSkeleton;
            }
        }
        public override PointCollectionsManager NewPSkeleton
        {
            get
            {
                return PolarAxis.NewPSkeleton;
            }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("PolarAxis"), TypeConverter(typeof(ExpandableObjectConverter))]
        public PolarAxis PolarAxis
        {
            get { return jz; }
            set
            {
                jz?.InHosts.Remove(this);
                jz = value;
                jz?.InHosts.Add(this);
            }
        }
        [MultilingualDisplayName("PolarCoordinatePole")]
        public override PointBase OriginPoint
        {
            get
            {
                return base.OriginPoint;
            }

            set
            {
                base.OriginPoint = value;
            }
        }
        [MultilingualCategory("View"), MultilingualDisplayName(null, "Show", "Ox"), DefaultValue(typeof(bool), "True"), TypeConverter(typeof(ArtMath.Converter.BooleanConverter))]
        public bool ShowOx
        {
            get { return showOx; }
            set
            {
                showOx = value;
                Pad.Canvas.Invalidate();
            }
        }
        [MultilingualDisplayName("PolePosition")]
        public override RPointS OriginCoordinate
        {
            get
            {
                return base.OriginCoordinate;
            }

            set
            {
                base.OriginCoordinate = value;
            }
        }
        public override void ForEachStraightLine(Predicate<StraightLineBase> act)
        {
            if (act == null) return;
            act(PolarAxis);
        }
        public override void CoordinateChanged(PointsRelocationReason reason)
        {
            if (Pad.Location.Y + OriginCoordinate.Y > Pad.Canvas.Height - 25)
            {
                PolarAxis.GraduationTextLocation = AxisTextLocation.Above;
            }
            else
            {
                PolarAxis.GraduationTextLocation = AxisTextLocation.Below;
            }
            base.CoordinateChanged(reason);
        }
        //public override bool Selected_
        //{
        //    get
        //    {
        //        return base.Selected_;
        //    }

        //    set
        //    {
        //        base.Selected_ = value;
        //        if (PolarAxis != null)
        //        {
        //            PolarAxis.Selected_ = Selected_;
        //        }
        //    }
        //}
        //public override StyleState StyleState_
        //{
        //    get
        //    {
        //        return base.StyleState_;
        //    }

        //    set
        //    {
        //        base.StyleState_ = value;
        //        if (PolarAxis != null)
        //        {
        //            PolarAxis.StyleState_ = StyleState_;
        //        }
        //    }
        //}
        //public override bool Visible
        //{
        //    get
        //    {
        //        return base.Visible;
        //    }

        //    set
        //    {
        //        base.Visible = value;
        //        if (PolarAxis != null) PolarAxis.Visible = Visible;
        //    }
        //}
        public override void InChildrenIterator(Predicate<ShapeBase> act)
        {
            if (act == null) return;
            if (PolarAxis != null)
            {
                if (!act(PolarAxis)) return;
            }
            //base.InChildrenIterator(act);
        }
        protected override double ScaleX
        {
            get
            {
                return PolarAxis.Scale.Value;
            }
        }
        protected override double ScaleY
        {
            get
            {
                return PolarAxis.Scale.Value;
            }
        }
        protected override double UnitX
        {
            get
            {
                return PolarAxis.Unit.Value;
            }
        }
        protected override double UnitY
        {
            get
            {
                return PolarAxis.Unit.Value;
            }
        }
        //public override PointD[] GetCrossPoints(ShapeBase shape, bool getNew = true)
        //{
        //    List<PointD> res = new List<PointD>();
        //    PointD[] pts = PolarAxis.GetCrossPoints(shape, getNew);
        //    if (pts != null) res.AddRange(pts);
        //    if (res.Count == 0) return null;
        //    return res.ToArray();
        //}

        //protected override void SetChildrenLinesColor()
        //{
        //    if (PolarAxis != null)
        //    {
        //        PolarAxis.LineColor = LineColor;
        //    }
        //    base.SetChildrenLinesColor();
        //}
        //protected override void SetChildrenLinesDashStyle()
        //{
        //    if (PolarAxis != null)
        //    {
        //        PolarAxis.LineDashStyle = LineDashStyle;
        //    }
        //    base.SetChildrenLinesDashStyle();
        //}
        //protected override void SetChildrenLinesWidth()
        //{
        //    if (PolarAxis != null)
        //    {
        //        PolarAxis.LineWidth.SetExpression(LineWidth.Expression);
        //    }
        //    base.SetChildrenLinesWidth();
        //}
        public override void RotateCenter_CoordinateChanged(PointD oldValue, PointD newValue)
        {
            PPointS ss = RotateCenter as PPointS;
            rotatePCenter = RTtoPxy(ss.ToPPointD()) + OriginCoordinate.ToPointD();
            jz.PSlope = Math.Tan(-RotateAngle.RadValue);
        }
        public PointD RTtoPxy(PointD RT, bool adaptAngleUnit = true)
        {
            return XYToPxy(RTtoXY(RT, adaptAngleUnit));
            //if (adaptAngleUnit)
            //{
            //    if (unit == AngleUnit.Degree) RT.Y *= Angle.DToR;
            //}
            //return new PointD(RT.X * Math.Cos(RT.Y) * PolarAxis.Scale.Value,
            //    -RT.X * Math.Sin(RT.Y) * PolarAxis.Scale.Value).Rotate(RotateAngle.Angle.RadValue);
        }
        public PointD PxytoRT(PointD Pxy, bool adaptAngleUnit = true)
        {
            return XYtoRT(PxyToXY(Pxy), adaptAngleUnit);
            //double cos = Math.Cos(-RotateAngle.Angle.RadValue), sin = Math.Sin(-RotateAngle.Angle.RadValue),
            //    D = (cos * cos + sin * sin) * PolarAxis.Scale.Value * PolarAxis.Scale.Value,
            //    Dx = Pxy.X * (cos * PolarAxis.Scale.Value) + Pxy.Y * (sin * PolarAxis.Scale.Value),
            //    Dy = (cos * PolarAxis.Scale.Value) * Pxy.Y - (sin * PolarAxis.Scale.Value) * Pxy.X,
            //    angle = Math.Atan2(-Dy / D, Dx / D);
            //if (angle < 0) angle += Core.Helper.Angle.RadRound;
            //if (adaptAngleUnit)
            //{
            //    if (unit == AngleUnit.Degree) angle *= Core.Helper.Angle.RToD;
            //}
            //return new PointD(Math.Sqrt((Dx / D) * (Dx / D) + (Dy / D) * (Dy / D)), angle);
        }
        public PointD RTtoXY(PointD RT, bool adaptAngleUnit = true)
        {
            if (adaptAngleUnit)
            {
                if (Pad.AngleUnit == AngleUnit.Degree) RT.Y *= Core.Helper.Angle.DToR;
            }
            return RT.X * Utility.GetUnitVector(RT.Y);
        }
        public PointD XYtoRT(PointD XY, bool adaptAngleUnit = true)
        {
            double rou = Math.Sqrt(XY.X * XY.X + XY.Y * XY.Y), theta = new PointD(0, 0).GetAngle(XY);
            if (adaptAngleUnit)
            {
                if (Pad.AngleUnit == AngleUnit.Degree) theta *= Core.Helper.Angle.RToD;
            }
            return new PointD(rou, theta);
        }
        //public override void CheckInRegion(RectangleD rect)
        //{
        //    PolarAxis.CheckInRegion(rect);
        //    base.CheckInRegion(rect);
        //}
        public override void Paint(Graphics gra)
        {
            if (ObjectState == ObjectState.Normal && Visible)
            {
                gra.RotateTransform((float)-RotateAngle.DegreeValue);
                PolarAxis.Paint(gra);
                gra.RotateTransform((float)RotateAngle.DegreeValue);
            }
            base.Paint(gra);
        }
        public override void CreateComponents()
        {
            PolarAxis = new PolarAxis(Pad);
            OriginPoint = new PolarCoordinateOriginPoint(Pad);
            Pad.TryCreateObject(OriginPoint);
            PolarAxis.CreateComponents();
            PolarAxis.SetPoint(0, OriginPoint);
            base.CreateComponents();
        }
        public override void UseFormat(Base obj)
        {
            base.UseFormat(obj);
            RectangularCoordinate rc = obj as RectangularCoordinate;
            if (rc != null)
            {
                if (Settings.Instance.ViewUseFormat)
                {
                    ShowOx = rc.ShowxOy;
                }
            }
        }
    }
}
